/* $RCSFile: PageRadPanelMenuNavigation.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/UI/WebControls/PageRadPanelMenuNavigation.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:30  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using AddonNice.Core;
using AddonNice.Diagnostics;
using AddonNice.Design;
using AddonNice.Configuration;
using AddonNice.Configuration.Settings;
using AddonNice.Security;
using AddonNice.Settings;
using AddonNice.Helpers;

using Telerik.Web.UI;

using Trace2    =   System.Diagnostics.Trace;
using Cache2    =   AddonNice.Settings.Cache.CurrentCache;

namespace AddonNice.UI.WebControls 
{ 

	/// <summary>
	/// PageRadPannelMenu Presents menus in a page using RadMenus et RadPanels
	/// and adds the 'glue' to link to tabs tree.
	/// </summary>
	public class PageRadPanelMenuNavigation : Table, INavigation , IPortalMenu
	{ 
        int currentDepth                    =   0; // working value when building menus
        List<RadPanelBar> PanelsList        =   new List<RadPanelBar>();
        PagesDB PgDB                        =   new PagesDB();

        PortalSettings _portalSettings; 
        PortalSettings portalSettings 
        {
            get 
            {
                if ( _portalSettings == null )
                    _portalSettings = (PortalSettings)HttpContext.Current.Items[StStr.strPortalSettings];
                return _portalSettings;
            }
        }

		/// <summary> 
		/// Indicates if control should use a single RadPanel or more complex structure with menus
		/// </summary> 
        bool _RadPanelOnly  =   true;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public bool RadPanelOnly 
		{ 
			get{return _RadPanelOnly;} 
			set{_RadPanelOnly = value;} 
		} 


        PanelBarExpandMode _ExpandMode  =   PanelBarExpandMode.MultipleExpandedItems;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public PanelBarExpandMode ExpandMode 
		{ 
			get{return _ExpandMode;} 
			set{_ExpandMode = value;} 
		} 

		bool _TrackClientMouse = true;
        /// <summary> 
		/// Should control send items tooltip in status
        /// Default true;
		/// </summary> 
		[ Category("Data"), PersistenceMode(PersistenceMode.Attribute) ] 
		public bool TrackClientMouse 
		{ 
			get{return _TrackClientMouse;} 
			set{_TrackClientMouse = value;} 
		} 

        /// <summary> 
		/// Indicates if control should display full menu tree or only a limited number of sub levels
        /// calling itself each time with a new origin to parse
		/// </summary> 
        bool _FullMenus     =   true;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public bool FullMenus 
		{ 
			get{return _FullMenus;} 
			set{_FullMenus = value;} 
		} 

        /// <summary> 
		/// sub levels deep limit when displaying root based menus
		/// </summary> 
        int _RootSubLevels  =   0;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public int RootSubLevels
		{ 
			get{return _RootSubLevels;} 
			set{_RootSubLevels = value;} 
		} 

        /// <summary> 
		/// sub levels deep limit
		/// </summary> 
        int _SubLevels      =   0;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public int SubLevels
		{ 
			get{return _SubLevels;} 
			set{_SubLevels = value;} 
		} 

		bool _ShowImages    =   true;
		/// <summary> 
		/// Indicates if control should show the images
		/// </summary> 
		[ Category("Data"), PersistenceMode(PersistenceMode.Attribute) ] 
		public bool ShowImages 
		{ 
			get{return _ShowImages;} 
			set{_ShowImages = value;} 
		} 

        /// <summary> 
		/// CellPadding for internal table (used to ajust image and RadPanel
		/// </summary> 
        int _PanelCellPadding  =   4;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public int PanelCellPadding
		{ 
			get{return _PanelCellPadding;} 
			set{_PanelCellPadding = value;} 
		} 

        /// <summary> 
		/// CellSpacing for internal table (used to ajust image and RadPanel
		/// </summary> 
        int _PanelCellSpacing  =   4;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public int PanelCellSpacing
		{ 
			get{return _PanelCellSpacing;} 
			set{_PanelCellSpacing = value;} 
		} 

        
        
        string _MenuSkin        =   string.Empty;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
        public string MenuSkin
        {
            get
            {
                return _MenuSkin;
            }
            set
            {
                _MenuSkin = value;
            }
        }

        int _NbColumns          =   2;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
        public int NbColumns
        {
            get
            {
                return _NbColumns;
            }
            set
            {
                _NbColumns = value;
            }
        }

        // Large icon width ( normally 48px )
        Unit _LargeImgWidth  =   new Unit("48px");
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
        public Unit LargeImgWidth
        {
            get
            {
                return _LargeImgWidth;
            }
            set
            {
                _LargeImgWidth = value;
            }
        }

        // Empty means let full image size
        Unit _SmallImgHeight  =   Unit.Empty;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
        public Unit SmallImgHeight
        {
            get
            {
                return _SmallImgHeight;
            }
            set
            {
                _SmallImgHeight = value;
            }
        }

        // Empty means let extend to needed size
        Unit _MenuHeight  =   Unit.Empty;
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
        public Unit MenuHeight
        {
            get
            {
                return _MenuHeight;
            }
            set
            {
                _MenuHeight = value;
            }
        }
		
        #region SiteMap

        private bool _ShowSiteMap = true;
		/// <summary> 
		/// Should we display SiteMap
		/// </summary> 
		[Category("SiteMap"), PersistenceMode(PersistenceMode.Attribute)] 
		public bool ShowSiteMap 
		{ 
			get{return _ShowSiteMap;} 
			set{_ShowSiteMap = value;} 
		} 
        string _SiteMapProvider="ADNSiteMapMenuProvider" ;
        [Category("SiteMap"), PersistenceMode(PersistenceMode.Attribute)] 
		public string SiteMapProvider 
		{ 
			get{return _SiteMapProvider;} 
			set{_SiteMapProvider = value;} 
		} 
        string _PathSeparator    =   " : ";
        [Category("SiteMap"), PersistenceMode(PersistenceMode.Attribute)] 
		public string PathSeparator
		{ 
			get{return _PathSeparator;} 
			set{_PathSeparator = value;} 
		} 
        Style _PathSeparatorStyle   =   null;
        [Category("SiteMap"), PersistenceMode(PersistenceMode.Attribute)] 
		public Style PathSeparatorStyle
		{ 
			get{return _PathSeparatorStyle;} 
			set{_PathSeparatorStyle = value;} 
		} 

        Style _CurrentNodeStyle  =   null;
		public Style CurrentNodeStyle
		{ 
			get{return _CurrentNodeStyle;} 
			set{_CurrentNodeStyle = value;} 
		} 
        Style _NodeStyle  =   null;
		public Style NodeStyle
		{ 
			get{return _NodeStyle;} 
			set{_NodeStyle = value;} 
		} 
        Style _RootNodeStyle  =   null;
		public Style RootNodeStyle
		{ 
			get{return _RootNodeStyle;} 
			set{_RootNodeStyle = value;} 
		} 
        #endregion SiteMap
		
		#region INavigation implementation 
		
        private BindOption _bind        =   BindOption.BindOptionTop; 
		private int _definedParentTab   =   -1;

		private bool _useTabNameInUrl   =   false;
		/// <summary> 
		/// Indicates if control should show the tabname in the url 
		/// </summary> 
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public bool UseTabNameInUrl 
		{ 
			get{return _useTabNameInUrl;} 
			set{_useTabNameInUrl = value;} 
		} 

		private bool _autoBind = false; 

		/// <summary> 
		/// Indicates if control should bind when loads 
		/// </summary> 
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public bool AutoBind 
		{ 
			get{return _autoBind;} 
			set{_autoBind = value;} 
		} 

		/// <summary> 
		/// Describes how this control should bind to db data 
		/// </summary> 
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)] 
		public BindOption Bind 
		{ 
			get {return _bind;} 
			set 
			{ 
				if(_bind != value) 
				{ 
					_bind = value; 
				} 
			} 
		} 

        /// <summary>
		/// defines the parentPageID when using BindOptionDefinedParent
		/// </summary>
		[Category("Data"), PersistenceMode(PersistenceMode.Attribute)]
		public int ParentPageID
		{ 
			get {return _definedParentTab;}
			set
			{
				if(_definedParentTab != value)
				{
					_definedParentTab = value;
				}
			}
		}

        /// <summary>
		/// This is the real Parent used for menu construct when in mode FullMenu == false
		/// </summary>
		int CurrentParentPageID
		{ 
			get 
            {
                // first get it from querystring if present
                if ( Context != null 
                    && Context.Request.QueryString[StStr.strCurrentParentPageID] != null )
                {
                    string newId                            =   Context.Request.QueryString[StStr.strCurrentParentPageID];
                    int nID                                 =   int.Parse(newId);
                    ViewState[StStr.strCurrentParentPageID] =   nID;
                    return nID;
                }
                object ob                                   =   ViewState[StStr.strCurrentParentPageID];
                if (ob == null)
                {
                    ViewState[StStr.strCurrentParentPageID] =   ParentPageID;
                    ob                                      =   ParentPageID;
                }
                return (int)ob;
            }
			set
			{
                    ViewState[StStr.strCurrentParentPageID]    =   value;
			}
		}

        bool isRoot
        {
            get
            {
                return ( CurrentParentPageID <= 0 );
            }
        }
        
        
        #endregion 

        
        bool _HideUnderCrm = false;
		/// <summary> 
		/// Should control be hidden when under Crm 
        /// default: false
		/// </summary> 
		[ Category("Data"), PersistenceMode(PersistenceMode.Attribute) ] 
		public bool HideUnderCrm
		{ 
			get{return _HideUnderCrm;} 
			set{_HideUnderCrm = value;} 
		} 
        
        bool _IsPortalMenus = false;
		/// <summary> 
		/// Should control act as a portal menu
        /// default: false
		/// </summary> 
		[ Category("Data"), PersistenceMode(PersistenceMode.Attribute) ] 
		public bool IsPortalMenus 
		{ 
			get{return _IsPortalMenus;} 
			set{_IsPortalMenus = value;} 
		} 
        
        #region IPortalMenu implementation
        
        public void ResetCache()
        {
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation ResetCache BEG Items.Count: {0}.", PanelsList.Count),NavTraceSwitch.Sw.Info);
            Cache2.RemoveGlobalPagesCacheKey();
        }

        public void Rebind()
        {
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation Rebind BEG Items.Count: {0}.", PanelsList.Count),NavTraceSwitch.Sw.Info);
            foreach (RadPanelBar pn in PanelsList)
            {
                pn.ClearSelectedItems();
                pn.Items.Clear();
            }
            InitData();
            if (AutoBind)
                DataBind();
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation Rebind END IsPostBack: {0}.", PanelsList.Count),NavTraceSwitch.Sw.Info);
        }
       
        public bool SelectMenuItem(int wPageId)
        {
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SelectMenuItem BEG PageId: {0}.", wPageId),NavTraceSwitch.Sw.Info);
            bool found          =   false;
            foreach (RadPanelBar pn in PanelsList)
            {
                RadPanelItem it =   pn.FindItemByValue(wPageId.ToString());
                found           =   (it != null);
                if (found)
                {
                    it.Selected = true;
                    break;
                }
            }
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SelectMenuItem END found: {0}.", found),NavTraceSwitch.Sw.Info);
            return found;
        }

        public Control AjaxControl
        {
            get
            {
                return this;
            }
        }

        public bool ShouldRegisterInAjaxManager
        {
            get
            {
                return true;
            }
        }

        #endregion IPortalMenu


        protected override void OnInit(EventArgs e)
        {
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation OnInit BEG IsPostBack: {0}, AutoBind: {1}, ShowImages: {2}", Page.IsPostBack,AutoBind,ShowImages),NavTraceSwitch.Sw.Info);
            InitData();
            // Registers in portal
            if ( IsPortalMenus )
                portalSettings.AddPortalMenu(this);
            base.OnInit(e);
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation OnInit END PanelsList.count: {0}.", PanelsList.Count),NavTraceSwitch.Sw.Info);
        }


        /// <summary>
        /// Ctor init load handler
        /// </summary>
        public PageRadPanelMenuNavigation() 
		{ 
			EnableViewState =   true; 
			Load            +=  new EventHandler(LoadControl);
		} 

		private void LoadControl(object sender, EventArgs e) 
		{
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation LoadControl BEG IsPostBack: {0}, AutoBind: {1}", Page.IsPostBack,AutoBind),NavTraceSwitch.Sw.Info);
            if (!Page.IsPostBack)
            {
                if (AutoBind)
                    DataBind();
            }
		}

        /// <summary>
		/// Init internal data
		/// </summary>
        protected void InitData()
        {
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation InitData BEG HideUnderCrm: {0}", HideUnderCrm),NavTraceSwitch.Sw.Info);
            // Must hide menu under CRM 
            if (HideUnderCrm && PortalSettings.IsUnderCRM)
            {
                Visible                 =   false;
                return;
            }
            currentDepth                =   0;
            // Build list of tabs to be shown to user 
            AuthorizedPageStripDetail authorizedTabs = new AuthorizedPageStripDetail(Bind,ParentPageID,CurrentParentPageID);
            
            ParentPageID                =   authorizedTabs.ParentPageID;
            CurrentParentPageID         =   authorizedTabs.CurrentParentPageID;

            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation InitData authorizedTabs.Count: {0}", authorizedTabs.Count),NavTraceSwitch.Sw.Info);
            TableRow trw                =   new TableRow();
            trw.VerticalAlign           =   VerticalAlign.Top;
            if ( MenuHeight != Unit.Empty )
                trw.Height              =   MenuHeight;
            int nbCells                 =   0;
            bool isForm                 =   (Config.AuthenticationMode == System.Web.Configuration.AuthenticationMode.Forms );
            IAddonNiceUser    curUser   =   PortalSettings.CurrentUser;
            bool isAuthenticated        =   ( curUser != null ) ? !curUser.IsAnonymous : false;
            for (int i = 0; i < authorizedTabs.Count; i++)
            {
                PageStripDetails myPage = authorizedTabs[i];
                //Get ride of unecessary items
                if (!myPage.OkForMenus)
                    continue;
                if (!isForm && myPage.FormsOnly)
                    continue;
                if (!isAuthenticated && myPage.AuthenticatedOnly )
                    continue;
                AddMainRadPanel(i, trw, myPage);
                if ((nbCells % NbColumns) == (NbColumns - 1))
                {
                    Rows.Add(trw);
                    trw                 =   new TableRow();
                    trw.VerticalAlign   = VerticalAlign.Top;
                    if ( MenuHeight != Unit.Empty )
                        trw.Height      =   MenuHeight;
                }
                nbCells++;
            }
            // must fill the row with as many empty cells as necessary
            int k                       =   nbCells % NbColumns;
            if ( k != 0 )
            {
                int i                   =   NbColumns - k;
                while (i > 0)
                {
                    TableCell cl        =   new TableCell();
                    trw.Cells.Add(cl);
                    i--;
                }
                Rows.Add(trw);
            }
            if (ShowSiteMap )
            {
                trw                     =   new TableRow();
                TableCell cl            =   new TableCell();
                cl.ColumnSpan           =   NbColumns;
                SiteMapPath mp          =   new SiteMapPath();
                mp.PathSeparator        =   PathSeparator;
                mp.SiteMapProvider      =   SiteMapProvider;
                if ( PathSeparatorStyle != null )
                    mp.PathSeparatorStyle.CopyFrom(PathSeparatorStyle);
                if ( CurrentNodeStyle != null)
                    mp.CurrentNodeStyle.CopyFrom(CurrentNodeStyle);
                if ( NodeStyle != null)
                    mp.NodeStyle.CopyFrom(NodeStyle);
                if ( RootNodeStyle != null)
                    mp.RootNodeStyle.CopyFrom(RootNodeStyle);
                cl.Controls.Add(mp);
                trw.Cells.Add(cl);
                Rows.Add(trw);
            }
        } 
        
        /// <summary>
        /// Create an url point to this page send a query string containing the desired ParentPageID to start menu hierarchy
        /// </summary>
 		private string CreateLocalUrl(int id) 
		{
            string tab      =   portalSettings.ActivePageSettings.PageKeyPhrase;
			string auxtab   =   string.Empty;
			foreach (char c in tab)
				if (char.IsLetterOrDigit(c)) 
                    auxtab  +=  c; 
                else auxtab +=  "_";
			string url      =   HttpUrlBuilder.BuildUrlWithCustomAttributes(portalSettings.ActivePageSettings.PageID,string.Format("{0}={1}",StStr.strCurrentParentPageID,id));
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation CreateLocalUrl id: {0}, url: {1}", id, url),NavTraceSwitch.Sw.Info);
            return url;
		}
 
        /// <summary>
        /// Extract the image url from skinid for main RadPanel
        /// </summary>
        void SetImageUrl(Image im, string wSkinID)
        {
            try
            {
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetImageUrl wSkinID: {0}", wSkinID),NavTraceSwitch.Sw.Info);
                Hashtable skTb  =   portalSettings.GetSkinImageMenu(false);
                bool okSkin     =   (skTb[wSkinID] != null);
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetImageUrl OkSkin: {0}, wSkinID: {1}, skTb.Count: {2}", okSkin,wSkinID,skTb.Count),NavTraceSwitch.Sw.Info);
                if (okSkin)
                {
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetImageUrl skTb[wSkinID] : {0}", skTb[wSkinID]),NavTraceSwitch.Sw.Info);
                    im.ImageUrl         =    (string)skTb[wSkinID];
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetImageUrl mn.ImageUrl: {0}", im.ImageUrl),NavTraceSwitch.Sw.Info);
                }
            }
            catch (Exception ex)
            {
                if ( NavTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageRadPanelMenuNavigation SetImageUrl ex: {0}", ex),NavTraceSwitch.Sw.Info);
            }
        }

        
        /// <summary> 
		/// Add a  RadPanelBar in the current row, using a cell
		/// </summary> 
		protected virtual void AddMainRadPanel(int idx,TableRow dl1,PageStripDetails myPage) 
		{
            bool okRole			=	PortalSecurity.IsUserInRoles(myPage.AuthorizedRoles);
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel PageName: {0}, PageID: {1}, OkRole: {2}, Roles: {3}", 
                    new object[] { myPage.PageName, myPage.PageID, okRole, myPage.AuthorizedRoles }),NavTraceSwitch.Sw.Info);
            if (!okRole) 
                return;
			
            TableCell cl1       =   new TableCell();
            string swdt         =   string.Format("{0}%",100/NbColumns);
            cl1.Width           =   new Unit(swdt);
            dl1.Cells.Add(cl1);
                            
            Table tb            =   new Table();
            tb.Width            =   new Unit("100%");
            tb.CellPadding      =   PanelCellPadding;
            tb.CellSpacing      =   PanelCellSpacing;
            TableRow r          =   new TableRow();
            
            TableCell cl        =   new TableCell();
            cl.VerticalAlign    =   VerticalAlign.Top;
			Image im            =   new Image();
            im.ID               =   string.Format("img_{0}",idx);
            im.ImageAlign       =   ImageAlign.Baseline;
            string wSkinID      =   myPage.PageImage.ToLower(CultureInfo.InvariantCulture);
            if (string.IsNullOrEmpty(wSkinID))
                wSkinID         =   "defaultskin";

            SetImageUrl(im,wSkinID);
            cl.Controls.Add(im);
            if ( LargeImgWidth != Unit.Empty )
            {
                cl.Width        =   LargeImgWidth;
            }
            r.Cells.Add(cl);

            cl                  =   new TableCell();

            RadPanelBar pn	    =	new RadPanelBar();
            // keep it in a list for fast access
            PanelsList.Add(pn);
            pn.Skin             =   SkinID;
            pn.ExpandMode       =   ExpandMode;
            //pn.ExpandAnimation  =   ExpandAnimation;
            //pn.CollapseAnimation  =   CollapseAnimation;
            if ( MenuHeight != Unit.Empty )
                pn.Height       =   MenuHeight;
            
            RadPanelItem mn	    =	new RadPanelItem(myPage.PageKeyPhrase);
            if ( myPage.PageID == StStr.WelcomePageID ) // We track Welcome Page to Add the Portal Name
                    mn.Text     =   string.Format("{0} {1}",myPage.PageKeyPhrase,portalSettings.PortalName);
            mn.ToolTip          =   mn.Text;
			mn.Value		    =	myPage.PageID.ToString();
            mn.Width            =   new Unit("100%");
            mn.Expanded         =   true;

            pn.Items.Add(mn);
			
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel PageName: {0}, PageID: {1}, PageImage: {2}", 
                    myPage.PageName,myPage.PageID,myPage.PageImage),NavTraceSwitch.Sw.Info);
            currentDepth++;
            // Url Pages potentially have no children 
            bool isUrl          =   ( myPage.Pages.Count == 0 ) ;
            if ( RadPanelOnly )
                    RecursePanelItem(myPage.Pages, mn);
            else    RecurseMainMenu(myPage.Pages, mn);
            currentDepth--;
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel PageName: {0}, Count: {1}, FullMenus: {2}", 
                    myPage.PageName,mn.Items.Count,FullMenus),NavTraceSwitch.Sw.Info);
            // Tabs without children are url's Tabs
            if ( isUrl )
                mn.NavigateUrl  =    MenuHelper.GiveMeUrl(myPage.PageKeyPhrase, myPage.PageID,myPage.Flags,UseTabNameInUrl);
            // For other Tabs we install an url that redirect to this page and allow opening a sub menu
            else if (!FullMenus) 
                mn.NavigateUrl  =    CreateLocalUrl(myPage.PageID);
            // small image if selected
            if ( ShowImages )
                SetPanelImageUrl(mn,wSkinID);
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel PageName: {0}, mn.NavigateUrl : {1}", myPage.PageName,mn.NavigateUrl),NavTraceSwitch.Sw.Info);

            cl.Controls.Add(pn);
            r.Cells.Add(cl);
            tb.Rows.Add(r);
            // if no submenus, we try to add a text for this menu
            // we take it from the localized page elements
            bool nulAtt         =   (mn.Attributes["HasMenu"] == null) ;
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel RadPanelOnly: {0}, mn.Items.Count: {1}.", 
                    RadPanelOnly,mn.Items.Count,nulAtt ),NavTraceSwitch.Sw.Info);
            if ( ( RadPanelOnly && ( mn.Items.Count == 0) ) ||
                ( !RadPanelOnly && nulAtt ) )
            {
                // one empty row
                r               =   new TableRow();
                cl              =   new TableCell();
                r.Cells.Add(cl);
                cl              =   new TableCell();
                Label lb        =   new Label();
                lb.SkinID       =   "MenuLabel";
                lb.Text         =   GetPageMetaDescription(myPage.PageID);
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation AddMainRadPanel Label.Text: '{0}'.", lb.Text),NavTraceSwitch.Sw.Info);
                cl.Controls.Add(lb);
                r.Cells.Add(cl);
                tb.Rows.Add(r);
            }
            cl1.Controls.Add(tb);
		}

        /// <summary>
        /// Try to extract the Meta Description from DB using current language then std
        /// </summary>
        string GetPageMetaDescription(int pgID)
        {
            CultureInfo ci  =   portalSettings.PortalContentLanguage;
			string langKey  =   StStr.PageMetaDescription_under+ ci.Name.ToUpper().Replace('-', '_');
			string langKey2 =   string.Empty;
            if ( !ci.IsNeutralCulture )
			    langKey2    =   StStr.PageMetaDescription_under+ ci.Parent.Name.ToUpper().Replace('-', '_');

            string result   =   PgDB.GetPageSingleCustomSettings(pgID,langKey);
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation GetPageMetaDescription PageId: {0}, langKey: {1}, RESULT: '{2}'", pgID,langKey,result),NavTraceSwitch.Sw.Info);
            if ( string.IsNullOrEmpty(result) )
            {
                if ( !ci.IsNeutralCulture )
                {
                    result = PgDB.GetPageSingleCustomSettings(pgID,langKey2);
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation GetPageMetaDescription PageId: {0}, langKey2: {1}, RESULT: '{2}'", pgID,langKey2,result),NavTraceSwitch.Sw.Info);
                }
                if ( string.IsNullOrEmpty(result) )
                {
                    langKey =   StStr.PageKeyPhrase;
                    result  =   PgDB.GetPageSingleCustomSettings(pgID,langKey);
                }
            }
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation GetPageMetaDescription PageId: {0}, langKey: {1}, RESULT: '{2}'", pgID,langKey,result),NavTraceSwitch.Sw.Info);
            return result;
        }

        /// <summary>
        /// Extract the image url from skinid and add it to a Panel Item
        /// </summary>
        void SetPanelImageUrl(RadPanelItem mn,string wSkinID)
        {
            try
            {
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetPanelImageUrl wSkinID: {0}", wSkinID),NavTraceSwitch.Sw.Info);
                Hashtable skTb          =   portalSettings.GetSkinImageMenu(true);
                bool okSkin             =   (skTb[wSkinID] != null);
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetPanelImageUrl OkSkin: {0}, wSkinID: {1}, skTb.Count: {2}", okSkin,wSkinID,skTb.Count),NavTraceSwitch.Sw.Info);
                if (okSkin)
                {
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetPanelImageUrl skTb[wSkinID] : {0}", skTb[wSkinID]),NavTraceSwitch.Sw.Info);
                    mn.ImageUrl         =   (string)skTb[wSkinID];
                    mn.ImagePosition    =   RadPanelItemImagePosition.Left;
                    mn.ToolTip          =   mn.Text;
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation SetPanelImageUrl mn.ImageUrl: {0}", mn.ImageUrl),NavTraceSwitch.Sw.Info);
                }
            }
            catch (Exception ex)
            {
                if ( NavTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageRadPanelMenuNavigation SetPanelImageUrl ex: {0}", ex),NavTraceSwitch.Sw.Info);
            }
        }

        protected virtual void RecursePanelItem(PageStripDetailsList t,RadPanelItem mn) 
		{ 
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecursePanelItem BEG sub pages Count: {0}, SubLevels: {1}, currentDepth: {2}",
                    new object[]{t.Count,SubLevels,currentDepth}),NavTraceSwitch.Sw.Info);
			// don't go under the limited depth
            if ( t.Count <= 0 || (isRoot && (currentDepth > RootSubLevels ) )
                || ( !isRoot && ( currentDepth > SubLevels ) ) )
                return;
			for (int c = 0; c < t.Count; c++) 
			{ 
				PageStripDetails mySubTab = t[c];
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecursePanelItem mySubTab.PageName: {0}, PageID: {1}", 
                        mySubTab.PageName, mySubTab.PageID),NavTraceSwitch.Sw.Info);
                if ( mySubTab.OkForMenus &&
                        PortalSecurity.IsUserInRoles(mySubTab.AuthorizedRoles)) 
				{
                    RadPanelItem mnc    =	new RadPanelItem(mySubTab.PageKeyPhrase);
                    mnc.ToolTip         =   mnc.Text;
					mnc.Value		    =	mySubTab.PageID.ToString();
                    if (ShowImages)
                    {
                        string wSkinID  =   mySubTab.PageImage.ToLower(CultureInfo.InvariantCulture);
                        if (string.IsNullOrEmpty(wSkinID))
                            wSkinID     =   "defaultskin";
                        SetPanelImageUrl(mnc, wSkinID);
                        if (SmallImgHeight != Unit.Empty )
                            mnc.Height  =   SmallImgHeight;
                    }
                    mn.Items.Add(mnc);
                    currentDepth++;
                    // Url Pages potentially have no children
                    bool isUrl      =   ( mySubTab.Pages.Count == 0 );
                    RecursePanelItem(mySubTab.Pages, mnc);
                    currentDepth--;
                    if ( mnc.Items.Count == 0 )
                    {
                        if ( NavTraceSwitch.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecursePanelItem FullMenu: {0}, Page.Count: {1}",FullMenus,mySubTab.Pages.Count),NavTraceSwitch.Sw.Info);
                        if ( FullMenus || isUrl )
                            mnc.NavigateUrl = MenuHelper.GiveMeUrl(mySubTab.PageKeyPhrase, mySubTab.PageID,mySubTab.Flags,UseTabNameInUrl);
                        else // we want to call ourself with the new ParenPageId
                        {
                            mnc.NavigateUrl = CreateLocalUrl(mySubTab.PageID);
                        }
                    }
                    else if (!FullMenus) // we want to call ourself with the new ParenPageId
                    {
                        mnc.NavigateUrl =   CreateLocalUrl(mySubTab.PageID);
                        mnc.Expanded    =   true;
                    }
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecursePanelItem Adding RadPanelItem Value: {0}.", mnc.Value),NavTraceSwitch.Sw.Info);
                } 
			} 
		}

        protected virtual void RecurseMainMenu(List<PageStripDetails> t,RadPanelItem mn) 
		{ 
			// don't go under the limited depth
            if ( t.Count <= 0 || (isRoot && (currentDepth > RootSubLevels ) )
                || ( !isRoot && ( currentDepth > SubLevels ) ) )
                return;
            RadMenu rmn             =   new RadMenu();
            rmn.Flow                =   ItemFlow.Vertical;
            rmn.SkinID              =   MenuSkin;
            rmn.Width               =   new Unit("100%");
			for (int c = 0; c < t.Count; c++) 
			{ 
				PageStripDetails mySubTab = t[c];
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecurseMainMenu mySubTab.PageName: {0}, PageID: {1}", 
                        mySubTab.PageName, mySubTab.PageID),NavTraceSwitch.Sw.Info);
                if ( mySubTab.OkForMenus &&
                        PortalSecurity.IsUserInRoles(mySubTab.AuthorizedRoles)) 
				{
                    RadMenuItem mnc =	new RadMenuItem(mySubTab.PageKeyPhrase);
                    mnc.ToolTip     =   mnc.Text;
                    mnc.Attributes["z-index"]   =   "-1";
					mnc.Value		=	mySubTab.PageID.ToString();
                    rmn.Items.Add(mnc);
                    currentDepth++;
                    bool isUrl      =   ( mySubTab.Pages.Count == 0 );
                    RecurseMenu(mySubTab.Pages, mnc);
                    currentDepth--;
                    if (mnc.Items.Count == 0)
                    {
                        if ( FullMenus || isUrl )
                            mnc.NavigateUrl = MenuHelper.GiveMeUrl(mySubTab.PageKeyPhrase, mySubTab.PageID,mySubTab.Flags,UseTabNameInUrl);
                        else // we want to call ourself with the new ParenPageId
                        {
                            mnc.NavigateUrl = CreateLocalUrl(mySubTab.PageID);
                        }
                    }
                    else if (!FullMenus) // we want to call ourself with the new ParenPageId
                    {
                        mnc.NavigateUrl = CreateLocalUrl(mySubTab.PageID);
                    }
                    if ( NavTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecurseMainMenu Adding RadMenuItem Value: {0}, to new RadMenu", mnc.Value),NavTraceSwitch.Sw.Info);
                } 
			} 
            if ( NavTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecurseMainMenu Adding RadMenuItem RadMenu.Items.Count", rmn.Items.Count),NavTraceSwitch.Sw.Info);
            if ( rmn.Items.Count > 0 )
            {
                mn.Attributes["HasMenu"]    =   StStr.strTrue;
                mn.Controls.Add(rmn);
            }

		}

        protected virtual void RecurseMenu(List<PageStripDetails> t,RadMenuItem mn) 
		{ 
			// don't go under the limited depth
            if ( t.Count <= 0 || (isRoot && (currentDepth > RootSubLevels ) )
                || ( !isRoot && ( currentDepth > SubLevels ) ) )
                return;

			for (int c=0; c < t.Count; c++) 
			{ 
				PageStripDetails mySubTab = t[c];
                if ( NavTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageRadPanelMenuNavigation RecurseMenu PageName: {0}, PageID: {1}, currentDepth: {2}", 
                        mySubTab.PageName, mySubTab.PageID,currentDepth),NavTraceSwitch.Sw.Info);
                if ( mySubTab.OkForMenus &&
                        PortalSecurity.IsUserInRoles(mySubTab.AuthorizedRoles)) 
				{
                    RadMenuItem mnc =	new RadMenuItem(mySubTab.PageKeyPhrase);
                    mnc.ToolTip     =   mnc.Text;
					mnc.Value		=	mySubTab.PageID.ToString();
                    mn.Items.Add(mnc);
                    currentDepth++;
                    bool isUrl      =   ( mySubTab.Pages.Count == 0 );
                    RecurseMenu(mySubTab.Pages, mnc);
                    currentDepth--;
                    if (mnc.Items.Count == 0)
                    {
                        if ( FullMenus || isUrl )
                            mnc.NavigateUrl = MenuHelper.GiveMeUrl(mySubTab.PageKeyPhrase, mySubTab.PageID,mySubTab.Flags,UseTabNameInUrl);
                        else // we want to call ourself with the new ParenPageId
                        {
                             mnc.NavigateUrl = CreateLocalUrl(mySubTab.PageID);
                        }
                    }
                    else if (!FullMenus) // we want to call ourself with the new ParenPageId
                    {
                        mnc.NavigateUrl = CreateLocalUrl(mySubTab.PageID);
                    }
                } 
			} 
		}
        
        protected override void OnPreRender(EventArgs e)
        {
            if (WebControlsTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RadPanelMenuNavigation OnPreRender BEG IsPostBack: {0}, Visible: {1}", Page.IsPostBack,Visible), WebControlsTraceSwitch.Sw.Info);

            // attaching the OnClientMouseOver/OnClientMouseOut javascript to onclick for the div

            if ( TrackClientMouse && !DesignMode )
            {
                ((ADNPage)Page).RegisterStatusScript();
            }
            base.OnPreRender(e);
            if (WebControlsTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]RadPanelMenuNavigation OnPreRender END.", WebControlsTraceSwitch.Sw.Info);
        }

 	} 
}